package lock;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import redis.clients.util.SafeEncoder;

/**
 * Redis key/value 序列化
 */
public class Serializer {

	public static byte[] keyToBytes(Object key) {
		return SafeEncoder.encode(key.toString());
	}

	public static String keyFromBytes(byte[] bytes) {
		return SafeEncoder.encode(bytes);
	}

	public static byte[][] keysToBytesArray(Object... keys) {
		byte[][] result = new byte[keys.length][];
		for (int i = 0; i < result.length; i++)
			result[i] = keyToBytes(keys[i]);
		return result;
	}

	public static Set<String> keySetFromBytesSet(Set<byte[]> data) {
		Set<String> result = new HashSet<String>();
		for (byte[] keyBytes : data)
			result.add(keyFromBytes(keyBytes));
		return result;
	}

	public static byte[] valueToBytes(Object value) {
		ObjectOutputStream fstOut = null;
		try {
			ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
			fstOut = new ObjectOutputStream(bytesOut);
			fstOut.writeObject(value);
			fstOut.flush();
			return bytesOut.toByteArray();
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			if (fstOut != null)
				try {
					fstOut.close();
				} catch (IOException e) {
				}
		}
	}

	public static Object valueFromBytes(byte[] bytes) {
		if (bytes == null || bytes.length == 0)
			return null;

		ObjectInputStream fstInput = null;
		try {
			fstInput = new ObjectInputStream(new ByteArrayInputStream(bytes));
			return fstInput.readObject();
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			if (fstInput != null)
				try {
					fstInput.close();
				} catch (IOException e) {
				}
		}
	}

	public static byte[][] valuesToBytesArray(Object... objectArray) {
		byte[][] data = new byte[objectArray.length][];
		for (int i = 0; i < data.length; i++)
			data[i] = valueToBytes(objectArray[i]);
		return data;
	}

	public static void valueSetFromBytesSet(Set<byte[]> data, Set<Object> result) {
		for (byte[] d : data)
			result.add(valueFromBytes(d));
	}

	@SuppressWarnings("rawtypes")
	public static List valueListFromBytesList(List<byte[]> data) {
		List<Object> result = new ArrayList<Object>();
		for (byte[] d : data)
			result.add(valueFromBytes(d));
		return result;
	}

}
